<!DOCTYPE html>
<html lang="zh-CN">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>时间轴</title>
    <link rel="shortcut icon" href="../static/baobao.png" type="image/png" />
    <style>
      /* 零、初始化样式 */
      body,div,p,span{
        padding: 0;
        margin: 0;
      }
      body{
        width: 100%;
        height: 100%;
        font-size: 13px;
        color: #333;
      }
      :root{
        --themecolor: #66ee66;
        --nextcolor: #75534b;
        --nextcolor-font: #d6bb9f;
         /* 下面用的都是中国色  http://zhongguose.com/ */
        --color1: #bf3553;
        --color2: #1661ab;
        --color3: #207f4c;
        --color4: #cf4813;
        --color5: #b52e78;
      }
      .btn,
      .noselect,
      .monthBox.active::after{ /* 禁止选中，选中后无蓝色底 */
        -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
        -webkit-user-select: none;
        -moz-user-focus: none;
        -moz-user-select: none;
        -ms-user-select: none;
        user-select: none;
      }
      
      
      /* 一、输入部分 */
      .wrapperIn{
        position: relative;
        width: 100%;
        min-height: 280px;
        text-align: center;
        background-image: url(./back.jpg);
        background-size: cover;
        box-shadow: 0 -6px 10px -7px var(--nextcolor) inset;
      }
      .wrapperIn.write::before{ /* 修改模式下加颜色层突出*/
        content: "";
        position: absolute;
        left: 0;
        top: 0;
        width: 100%;
        height: 100%;
        background-color: rgba(148, 114, 54, 0.4);
      }
      /* 1.输入下方的提示框-默认不显示 */
      .tipBtnBox{
        display: none;
        z-index: 10;
        position: absolute;
        left: 20%;
        top: 178px;
        width: 60%;
        line-height: 32px;
        color: #fff;
        font-size: 0.8em;
        text-align: left;
        background-color: rgba(66, 66, 66, 0.9);
        border-radius: 4px;
      }
      /* 1-1.提示框出现：当给它加上active或处于修改模式时 */
      .tipBtnBox.active,
      .write .tipBtnBox{
        display: block;
      }
      /* 1-2.提示按钮 */
      .tipBtnBox .btn{
        display: block;
        box-sizing: border-box;
        padding-left: 30px;
        cursor: pointer;
      }
      .btn.del,
      .write .btn{ /* 单项删除按钮del和修改模式下的按钮都不显示 */
        display: none;
      }
      .write .btn.del,
      .write .btn.deleteAll{  /* (续上)除非是修改模式下的删除按钮 */
        display: block;
      }
      .tipBtnBox .btn:hover{ 
        background-color: rgba(10, 10, 10, 0.3);
      }
      /* 2.输入框  ok表操作成功，error表操作失败 */
      .mainInput{
        z-index: 1;
        position: relative;
        box-sizing: border-box;
        margin: 120px auto auto;
        padding: 4px 8px;
        width: 60%;
        height: 34px;
        background-color: rgba(255, 255, 255, 0.7);
        box-shadow: 0 2px 6px -2px #fff;
        border: 1px solid #eee;
        border-radius: 4px;
        outline: none;
      }
      .mainInput.ok{
        box-shadow: 0 0 16px 0 #5dff80;
      }
      .mainInput.error{
        box-shadow: 0 0 16px 0 #ff6161;
      }
      .write .mainInput{ 
        border-color: var(--nextcolor);
        background-color: rgba(255, 255, 255, 1);
      }
      /* 2-1.输入框清空按钮× */
      .clearBtn{
        z-index: 2;
        position: absolute;
        top: 125px;
        left: calc(80% - 30px);
        width: 24px;
        height: 24px;
        line-height: 24px;
        font-size: 18px;
        text-align: center;
        color: var(--nextcolor-font);
        cursor: pointer;
      }
      .clearBtn:hover{
        color: var(--nextcolor);
      }
      /* 2-2.修改模式的标志 */
      .write .clearBtn::before{ 
        content: "修改模式";
        position: absolute;
        left: -86px;
        top: -23px;
        padding: 0 8px;
        font-size: 0.6em;
        line-height: 1.8em;
        color: #fff;
        background-color: var(--nextcolor);
        border-radius: 8px 8px 0 0;
      }
      /* 2-3.输入提示文本 */
      .wrapperIn::after{
        display: block;
        content: "【格式：xxxx年xx月 类型+内容】，还可输入"attr(data-left)"字";
        position: relative;
        margin: 6px auto auto;
        width: 59%;
        text-align: right;
        font-size: 0.8em;
        color: var(--nextcolor);
      }
      
      /* 二、内容部分 */
      .wrapperList{ /* 整体包裹 */
        display: grid;
        justify-content: center;
        box-sizing: border-box;
        width: 100%;
        max-height: 50%;
        margin-top: 40px;
        padding: 10px 30px;
      }
      /* 1.每个月份的包裹 */
      .monthBox{
        display: inline-block;
        position: relative;
        margin: 10px 10px 112px;
        padding-top: 18px;
      }
      .monthBox.active{ 
        margin-left: 40px;
      }
      .monthBox.active:nth-child(1){
        margin-left: 10px;
      }
      .monthBox::before{ /* 月份 - 都有 */
        display: block;
        content: attr(data-month)"月";
        position: absolute;
        left: 0;
        top: -36px;
        width: 100%;
        padding-bottom: 12px;
        font-size: 14px;
        font-weight: bold;
        text-align: center;
        text-shadow: 0 0 1px transparent,  0 0 2px #fff;
        color: var(--nextcolor);
        background-clip: content-box;
        border-bottom: 4px solid var(--nextcolor);
        border-radius: 8px;
      }
      .monthBox.active::after{ /* 年份 - active才有 */
        display: block;
        content: attr(data-year);
        position: absolute;
        left: 0;
        top: -108px;
        width: 56px;
        height: 56px;
        line-height: 56px;
        font-size: 18px;
        font-weight: bold;
        text-align: center;
        text-shadow: 0 0 1px transparent,  0 0 3px #fff;
        color: #fff;
        background-color: var(--nextcolor);
        box-shadow: 1px 1px 4px -2px #667648;
        border: 3px solid #fff;
        border-radius: 50%;
        cursor: pointer;
      }
      .monthBox.jump::after{ /* 前面存在空月-表示它是不连续的月份 */
        display: block;
        content: "";
        position: absolute;
        left: 0;
        top: -10px;
        width: 100%;
        height: 3px;
        background-color: var(--nextcolor);
        border-radius: 50%;
      }
      /* 1-1.每一项内容 */
      .monthBox span{
        display: inline-block;
        position: relative;
        box-sizing: border-box;
        padding-inline-start: 6px; /* 根据逻辑定位 */
        padding-inline-end: 4px; /* 根据逻辑定位 */
        max-height: 180px;
        line-height: 2em;
        writing-mode: vertical-lr; /* 垂直方向文本 - 隐患 - 微软雅黑加粗会叠加 */
        vertical-align: top;
        letter-spacing: 2px;
        word-break: break-all;
        border-block-end: 1px dotted var(--nextcolor); /* 根据逻辑定位 */
        border-radius: 2px;
        cursor: pointer;
        /* 打点省略   - 主要为了记录，没必要，要用的话需要再套一层标签才可以用*/
        /* text-overflow: ellipsis; */
        /* overflow: hidden; */
        /* display: -webkit-box;
        -webkit-line-clamp: 2;
        -webkit-box-orient: vertical; */
      }
      .monthBox span:hover::after{ /* 挂绳 */
       display: block;
       content: "";
       z-index: -1;
       position: absolute;
       top: -7px;
       left: 50%;
       width: 15px;
       height: 15px;
       border-left: 1px solid var(--nextcolor);
       border-top: 1px solid var(--nextcolor);
       transform: translateX(-50%) rotate(45deg);
      }
      /* 1-2.底部的类型按钮 */
      .signs{
        text-align: center;
        margin-bottom: 40px;
      }
      .signs span{
        position: relative;
        margin-left: 24px;
        margin-right: 6px;
        cursor: pointer;
      }
      /* 小圆点样式 --主定位 */
      .monthBox span::before,
      .signs span::before{
        display: block;
        content: "";
        position: absolute;
        top: -16px;
        left: 50%;
        transform: translateX(-50%);
        width: 8px;
        height: 8px;
        text-align: center;
        background-color: aqua;
        border-radius: 50%;
      }
      .signs span::before{
        top: 50%;
        left: -12px;
        transform: translateY(-50%);
      }
     
      /* 选中某项--处于修改模式下的突出 */
      .dataList span.writing.one,
      .dataList span.writing.two,
      .dataList span.writing.three,
      .dataList span.writing.four,
      .dataList span.writing.five{
        color: #fff;
        background-color: var(--nextcolor);
      }
      
      /*【选中某类型时1 --内容的字体颜色统一变弱】 */
      .dataList.one,
      .dataList.two,
      .dataList.three,
      .dataList.four,
      .dataList.five{
        color: var(--nextcolor-font);
      } 
      
      /* 【选中某类型时2 --内容的字体颜色突出】 */
      .one span.one{
        color: var(--color1);
      }
      .two span.two{
        color: var(--color2);
      }
      .three span.three{
        color: var(--color3);
      }
      .four span.four{
        color: var(--color4);
      }
      .five span.five{
        color: var(--color5);
      }
      
      /* 【选中某类型时3 --内容的字体变粗突出】 */
      .dataList.one span.one,
      .dataList.two span.two,
      .dataList.three span.three,
      .dataList.four span.four,
      .dataList.five span.five{
        font-family: SimHei, Arial, sans-serif;
        font-weight: bold;
        font-size: 1.1em;
      }
      
      
      /* 【配色】 项目前的圆点 鼠标滑过hover 类型前的圆点 */
      .monthBox span.one::before,
      .monthBox span.one:hover,
      .signs span.one::before{
        color: #fff;
        background-color: var(--color1);
      }
      
      .monthBox span.two::before,
      .monthBox span.two:hover,
      .signs span.two::before{
        color: #fff;
        background-color: var(--color2);
      }
      
      .monthBox span.three::before,
      .monthBox span.three:hover,
      .signs span.three::before{
        color: #fff;
        background-color: var(--color3);
      }
      
      .monthBox span.four::before,
      .monthBox span.four:hover,
      .signs span.four::before{
        color: #fff;
        background-color: var(--color4);
      }
      
      .monthBox span.five::before,
      .monthBox span.five:hover,
      .signs span.five::before{
        color: #fff;
        background-color: var(--color5);
      }
    
      /* 三、中间的小贴士相关样式 */
      .helpContent{
        display: none;
        position: fixed;
        top: 30%;
        left: 50%;
        transform: translateX(-50%);
        box-sizing: border-box;
        width: 60%;
        padding: 30px 40px;
        color: #fff;
        backdrop-filter: blur(8px);
        -webkit-backdrop-filter: blur(8px);
        background-color: rgba(56, 96, 52, 0.7);
        border-radius: 10px;
      }
      .helpContent.active{ /* active才显示 */
        display: block;
      }
      .helpContent::before{ /* 背景调色 */
        content: "";
        z-index: -2;
        position: absolute;
        left: 0;
        top: 0;
        width: 100%;
        height: 100%;
        background-color: rgba(10, 10, 10, 0.3);
        border-radius: 10px;
      }
      .helpContent div{
        font-weight: bold;
        text-align: center;
      }
      .helpContent p{
        margin-bottom: 20px;
        line-height: 1.6em;
        font-size: 0.9em;
      }
      .helpContent span{
        display: block;
        padding: 6px 0;
        font-size: 1.1em;
      }
      .helpContent .closeBtn{
        position: absolute;
        right: 18px;
        top: 12px;
        width: 28px;
        height: 28px;
        color: #fff;
        font-size: 18px;
        text-align: center;
        cursor: pointer;
      }
      .helpContent .closeBtn:hover{
        color: var(--themecolor);
      }
      /* 问号按钮 */
      .helpBtn{
        position: fixed;
        bottom: 86px;
        right: 24px;
        width: 42px;
        height: 42px;
        line-height: 42px;
        text-align: center;
        background-color: #fcfcfc;
        font-size: 16px;
        border-radius: 50%;
        -webkit-box-shadow: 0 1px 4px -2px rgb(0 0 0 / 13%), 0 2px 8px 0 rgb(0 0 0 / 8%), 0 8px 16px 4px rgb(0 0 0 / 4%);
        box-shadow: 0 1px 4px -2px rgb(0 0 0 / 13%), 0 2px 8px 0 rgb(0 0 0 / 8%), 0 8px 16px 4px rgb(0 0 0 / 4%);
        cursor: pointer;
      }
    </style>
  </head>
  <body>
    <!-- 第二步 允许输入 -->
    <div class="wrapperIn" data-left="28">
    <!-- 上面的 data-left 用作记录当前还允许输入的字数【通过伪元素显示】 -->
      <p class="tipBtnBox">
        <!-- 添加类名acitve时才显示； 内容是根据已存在的类型拼接的，会被替换 -->
        <!-- <span class="btn" onclick="oinput.value='学习+';oinput.focus()">1 学习+</span>
        <span class="btn del" onclick="oinput.value=saveInputData('del')">del 删除当前选中内容</span>
        <span class="btn deleteAll" onclick="oinput.value=saveInputData('deleteAll')">deleteAll 删除所有数据</span> -->
      </p>
      <!-- 下面输入框enter后的两种状态：添加类名ok或error -->
      <input class="mainInput" type="text" maxlength="28" placeholder="Enter输入(用中文句号分隔多项)" autofocus title="若年月省略则默认当前月"/>
      <span class="clearBtn noselect" title="点击清空输入框，双击退出修改模式" ondblclick="endEditFun()">×</span>
    </div>
    <div class="wrapperList">
      <div class="dataList">
        <!-- 上面div加上类名 one...five 5个类名可看到点击激活的效果-->
        <!-- <div class="monthBox active" data-month="3" data-year="2022">
          <span class="one">具体的一件事</span>
          <span class="two">完成了某个项目</span>
          <span class="three">某一项技能</span>
          <span class="four">...完成了某个项目</span>
          <span class="five">...某一项技能</span>
        </div>
        <div class="monthBox" data-month="4" data-year="2022">
          <span class="two">参加某个活动获奖了</span>
          <span class="three">尝试了某种方法，提高了效率</span>
        </div>
        <div class="monthBox jump" data-month="6" data-year="2022">
          <span class="one">厨艺长进，得到好评</span>
          <span class="three">通过合取谬误模型，再次了解了平凡也是伟大</span>
        </div> -->
      </div>
      <p class="signs noselect" onclick="highLightFun(event)">
        <!-- 后期根据实际数据生成内容 -->
        <!-- <span class="one">类型1</span>
        <span class="two">类型2</span>
        <span class="three">类型3</span>
        <span class="four">类型4</span>
        <span class="five">类型5</span> -->
      </p>
    </div>
    <div class="wrapperHelp">
      <div class="helpContent">
        <!-- 配合样式 添加类名acitve时才显示-->
        <div>小贴士</div>
        <p><span>【用户交互】</span>① 点击底部相应的类型，使对应类型内容突出；② 点击内容项进入修改模式(且输入 del 则删除该项)；③ 输入框中输入 deleteAll 将清空所有数据。</p>
        <p><span>【输入框要点】</span>单次输入量为28个字符，类型最多为五种，年月日期省略时默认取当前年月。</p>
        <p><span>【退出修改模式】</span> ① 再次单击选中的内容项；② 双击输入框右边的×按钮；③ 成功修改或删除后自动退出模式。</p>
        <span class="closeBtn" onclick="this.parentElement.classList.remove('active')">×</span>
      </div>
      <span class="helpBtn noselect">?</span>
    </div>
    <div style="height: 500px;"></div>
   
    <script>
      const owrapperIn = document.querySelector('.wrapperIn'); // 输入外框
      const oinput = document.querySelector('.mainInput');     // 输入框
      const otipBtnBox = document.querySelector('.tipBtnBox'); // 输入提示框
      const odataList = document.querySelector('.dataList');   // 内容列表
      const osigns = document.querySelector('.signs');         // 类型列表
      let timeLineTypeA = ['生活', '事业', '学习', '教学']; // 可删-赋值为[]
      let timeLineO = { // 可删-赋值为{}
        '2022年04月': [null, '参加某个活动获奖了。新增的同类型项', '尝试了某种方法，提高了效率', '★点击进入修改模式。修改本项内容。用按钮删除本项内容。或输入del删除当前项'],
      	'2022年03月': ['具体的一件事', '完成了某个项目', '某一项技能', '★退出修改模式。①再次单击。②双击×按钮。③成功enter操作后'],
        '2022年06月': [null, null, '通过合取谬误模型，再次了解了平凡也是伟大', '★非修改模式下：。1~5与d触发提示'],
        '2022年08月': [null, null, '删除所有数据：', '用按钮删除。或输入deleteAll删除']
      };
      if(localStorage.getItem('timeLine')){ // 初始化数据
        timeLineO = JSON.parse(localStorage.getItem('timeLine'));
        timeLineTypeA = JSON.parse(localStorage.getItem('timeLineType'));
      }
      const typeMapping = ['one', 'two', 'three', 'four', 'five'];
      
      function highLightFun(event){ // 突出某类型内容
        // 原理：根据点击获取当前元素对应的类名，给变色内容的父级加上此类名，通过设计父级带类名时的 CSS样式 来达到效果
        let ele = event.target;
        if(ele.nodeName === 'SPAN'){
          odataList.className = 'dataList ' + ele.className;
        }
      }
      let oChangingNode = null; // 修改模式中的修改对象
      let changingContent = ''; // 修改模式中修改对象的内容
      let changingDate = '';    // 修改模式中修改对象的日期
      function editOneFun(event){  // 点击->开启内容修改 -- 入口 
        let ele = event.target;
        if(ele.nodeName === 'SPAN'){ 
          // ① 修改样式状态
          if(oChangingNode){ // 清除上次选中内容的状态
            oChangingNode.classList.remove('writing');
          }
          if(oChangingNode !== ele){ // 和之前选中的不同
            oChangingNode = ele;
            owrapperIn.className = 'wrapperIn write';
            ele.classList.add('writing');
            // ② 内容放入输入框供修改（修改模式下输入del表示删除）
            changingContent = ele.innerText;
            let tmp = ele.parentElement.getAttribute('data-month') * 1;
            changingDate = ele.parentElement.getAttribute('data-year') + '年' + (tmp < 10 ? '0' + tmp : tmp) + '月';
            oinput.value = ele.innerText;
            owrapperIn.setAttribute('data-left', 28 - changingContent.length);
            oinput.focus();
          }else{ // 取消--单击已选中的
            endEditFun();
          }
        }
      }
      function endEditFun(){       // 退出修改模式 -- 出口
        // 修改样式状态，清空输入框和选中的元素节点
        if(oChangingNode){ // 清除上次选中内容的状态
          oChangingNode.classList.remove('writing');
          owrapperIn.className = 'wrapperIn';
          oinput.value = '';
          owrapperIn.setAttribute('data-left', 28);
          oChangingNode = null;
          changingContent = '';
          changingDate = '';
        }
      }
      
      oinput.onkeydown = function(event){ // 键盘enter事件触发
        let keycode = event.keyCode || event.which;
        let val = oinput.value.trim().replace(/\s/g, ' ');
        if (val && keycode === 13) { // 检测为enter键
          saveInputData(val);
        }
      }
      oinput.oninput = function(event){   // 输入监听--剩余字数 & 提示框
        let val = oinput.value.trim().replace(/\s/g, ' '); // 去多余空格
        owrapperIn.setAttribute('data-left', 28 - val.length); // 剩余字数跟进
        if(val.indexOf('d') === 0 || /^[12345]/.test(val)){ // 提示框
          otipBtnBox.className = 'tipBtnBox active';
        }else{
          otipBtnBox.className = 'tipBtnBox';
        }
      }
      document.querySelector('.clearBtn').onclick = function(){  // 清空输入
        oinput.value='';
        otipBtnBox.classList.remove('active');
        owrapperIn.setAttribute('data-left', 28);
      }
      document.querySelector('.helpBtn').onclick = function(){   // 打开小贴士
        document.querySelector('.helpContent').classList.add('active');
      }
      
      function saveInputData(val){  // 数据存储 -- 两类输入：新增 VS 修改 | 删掉全部信息
        let ischangMode = owrapperIn.classList.contains('write'); // 是否处于修改模式
        let isdeleteAll = val === 'deleteAll' ? true : false;     // 是否要求删掉全部信息
        let dataDate = null;  // 年月数据
        let dataIndex = null; // 索引数据 -> 类型 timeLineTypeA[dataIndex]
        let dataVal = null;   // 内容数据
        // ① 格式判断  “0000年00月 生活+具体的一件事”
        
        // A. 日期处理 dataDate
        if(!ischangMode && !isdeleteAll){ // 新增模式-非删除全部
          let hasDate = /^[\d]{4}年([\d]{2})月/.exec(val); // 如果有值，第一个为全匹配，第二个为子集；若无值，则为 null
          // console.log(hasDate);
          if(hasDate && hasDate[1] * 1 < 13 && hasDate[1] * 1 > 0){ // 正确日期
            dataDate = hasDate[0];
            val = val.slice(8).trim();
            // console.log(dataDate, val);
          }else{ // 没有标记日期 或 日期不对时采用当前日期且去掉错日期
            if(hasDate){
              val = val.slice(8).trim(); // 去掉--个数正确但无效的8位日期
            }
            let today = new Date();  // 时间对象
            let m = today.getMonth() + 1; // 月份范围0~11
            let nowYM = today.getFullYear() + '年' + (m < 10 ? '0'+ m: m) + '月';  // 当前年月
            dataDate = nowYM;
          }
        }else{ //修改中-不改日期
          dataDate = changingDate;
        }
        
        // ② 保存数据
        // B.类型处理 - 存在则找到索引dataIndex，不存在则添加dataVal
        let index = val.indexOf('+');
        if(!isdeleteAll && (index !== -1 || ischangMode)){  // 格式正确或修改模式-保存
          let type = ischangMode && oChangingNode ? oChangingNode.getAttribute('title') : val.slice(0, index);
          dataVal = ischangMode && oChangingNode ? changingContent : val.slice(index+1);
          
          let typeIndex = timeLineTypeA.indexOf(type);  // 找到对应的索引
          let hasLimit = false;
          if(typeIndex !== -1){ // 找到了
            dataIndex = typeIndex;
          }else{ // 找不到则 新增->限制下新增
            dataIndex = timeLineTypeA.length;
            if(dataIndex < 5){
              timeLineTypeA.push(type);
            }else{
              hasLimit = true;
            }
          }
          if(!hasLimit){ // 类型限制为5个，没超限制时执行
            if(timeLineO[dataDate]){ // 月份有数据
              let old = timeLineO[dataDate][dataIndex];
              let str = '';
              if(ischangMode){ // 修改模式
                let ttmp = val === 'del' ? '' : val;  // 替换的值ttmp
                str = old.replace(changingContent, ttmp);
                oChangingNode.classList.remove('writing');
                owrapperIn.className = 'wrapperIn';
                owrapperIn.setAttribute('data-left', 28);
                oChangingNode = null;
                changingContent = '';
                changingDate = '';
              }else{
                str = old ? old + '。' + dataVal : dataVal;
              }
              timeLineO[dataDate][dataIndex] = str.replace(/[。]+/g, '。');  // 句号的处理
            }else{
              timeLineO[dataDate] = [];
              timeLineO[dataDate][dataIndex] = dataVal;
            }
            if(/。$/.test(timeLineO[dataDate][dataIndex])){ // 去掉末尾句号
              timeLineO[dataDate][dataIndex] = timeLineO[dataDate][dataIndex].slice(0, -1);
            }
            // 判断是否删完一个月
            if(!timeLineO[dataDate].join('')){ // 替换后该月数据该月为空
              delete timeLineO[dataDate];
            }
            
            localStorage.setItem('timeLineType', JSON.stringify(timeLineTypeA));
            localStorage.setItem('timeLine', JSON.stringify(timeLineO));
            // ③ 渲染界面 并进行添加成功的提示
            showTimeList();
            oinput.className = 'mainInput ok';
            oinput.focus();
            oinput.value = '';
            owrapperIn.setAttribute('data-left', 28);
          }else{ // 超限制了报错
            oinput.className = 'mainInput error';
            otipBtnBox.className = 'tipBtnBox';
          }
          
        }else{ 
          if(isdeleteAll){ // 删除全部
            localStorage.removeItem('timeLineType');
            localStorage.removeItem('timeLine');
            timeLineTypeA = [];
            timeLineO = {};
            oinput.className = 'mainInput ok';
            oinput.value = '';
            odataList.innerHTML = '';
            osigns.innerHTML = '';
            owrapperIn.className = 'wrapperIn';
            owrapperIn.setAttribute('data-left', 28);
            oChangingNode = null;
            changingContent = '';
            changingDate = '';
          }else{ // 格式不对
            oinput.className = 'mainInput error';
          }
          otipBtnBox.className = 'tipBtnBox';
        }
        let t = setTimeout(function(){ 
          oinput.className = 'mainInput';
          t = null;
        }, 1500);
        return '';
      }
      function showTimeList(){      // 数据展示 -- 在页面刷新、数据改动时调用
        otipBtnBox.className = 'tipBtnBox';
        let str = '';
        let typestr = '';
        let tipstr = '';
        let keysA = Object.keys(timeLineO).sort(); // 年月集合并排序
        let y = 0;
        let m = 0;
        
        let typeNum = {};   // 假设每个类型对应一个量 => 检验类型内容存在否
        for(let k = 0; k < keysA.length; k++){ // 每月具体
          let ym = keysA[k];
          let newclass = y !== ym.slice(0, 4) ? ' active' : ''; // 第一个出现？
          newclass = !newclass && ym.slice(5, 7) * 1 - m !== 1 && m !== 0 ? ' jump': newclass; // && 的最终结果 取第一个false值或者最后一个值
          y = ym.slice(0, 4);
          m = ym.slice(5, 7) * 1;
          let tmp = '<div class="monthBox'+ newclass +'" data-month="'+m+'" data-year="'+y+'" title="'+y+'年" onclick="editOneFun(event)">';
          timeLineO[ym].map(function(item, index){ // 每个类型对应
            let arr = item ? item.split('。'): [];
            let tmptype = timeLineTypeA[index];
            // console.log(item, index);
            if(!item){
              typeNum[tmptype] = typeNum[tmptype]? typeNum[tmptype]:0; // 
            }else{ // 该月该类型不为空
              typeNum[tmptype] = typeNum[tmptype]? typeNum[tmptype]+1:1;
            }
            for(let l = 0; l < arr.length; l++){
              tmp += '<span class="'+typeMapping[index]+'" title="'+timeLineTypeA[index]+'">' + arr[l] + '</span>';
            }
          });
          str = str + tmp + '</div>';
        }
        // 判断该类型是否删完了
        // debugger;
        for(let type in typeNum){
          if(typeNum[type] < 1){
            let i = timeLineTypeA.indexOf(type);
            timeLineTypeA.splice(i, 1);
            for(let yymm in timeLineO){
              timeLineO[yymm].splice(i, 1);
            }
            localStorage.setItem('timeLineType', JSON.stringify(timeLineTypeA));
            localStorage.setItem('timeLine', JSON.stringify(timeLineO));
          }
        }
        odataList.innerHTML = str;
        
        timeLineTypeA.map(function(item, index){ // 每个类型对应
          typestr += '<span class="' + typeMapping[index] +'">' + item + '</span>';
          tipstr += '<span class="btn" onclick="oinput.value=\'' + item +'+\';oinput.focus()">' + (index+1) +' '+ item +'+</span>';
        });
        osigns.innerHTML = typestr;
        otipBtnBox.innerHTML = tipstr+'<span class="btn del" onclick="oinput.value=saveInputData(\'del\')">del 删除当前选中内容</span><span class="btn deleteAll" onclick="oinput.value=saveInputData(\'deleteAll\')">deleteAll 删除所有数据</span>';
        
        
      };
      showTimeList();
    </script>
  </body>
</html>